package com.larly.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.larly.annotation.AuthCheck;
import com.larly.common.BaseResponse;
import com.larly.common.DelectRequest;
import com.larly.common.PageRequest;
import com.larly.common.ResultUtils;
import com.larly.exception.ErrorCode;
import com.larly.exception.ThrowUtils;
import com.larly.model.domain.NoteLike;
import com.larly.model.domain.Notes;
import com.larly.model.domain.User;
import com.larly.model.domain.UserFollow;
import com.larly.model.dto.user.*;
import com.larly.model.dto.userfollow.UserFollowAddRequest;
import com.larly.model.vo.NotesVO;
import com.larly.model.vo.UserVO;
import com.larly.service.NoteLikeService;
import com.larly.service.impl.NotesServiceImpl;
import com.larly.service.impl.UserFollowServiceImpl;
import com.larly.service.impl.UserServiceImpl;
import com.larly.utils.IpAddressUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserServiceImpl userService;

    @Resource
    private UserFollowServiceImpl userFollowService;

    @Resource
    private NoteLikeService noteLikeService;
    @Autowired
    private NotesServiceImpl notesServiceImpl;

    /**
     * 注册
     *
     * @param userRegisterRequest
     * @return
     */
    @PostMapping("/register")
    public BaseResponse<Long> userRegister(@RequestBody UserRegisterRequest userRegisterRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(userRegisterRequest == null, ErrorCode.PARAM_ERROR);
        long result = userService.userRegister(userRegisterRequest);
        return ResultUtils.success(result);
    }

    /**
     * 登录
     *
     * @param userLoginRequest
     * @param request
     * @return
     */
    @PostMapping("/login")
    public BaseResponse<UserVO> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(userLoginRequest == null, ErrorCode.PARAM_ERROR);
        UserVO userVO = userService.userLogin(userLoginRequest, request);

        // 获取用户IP地址和地理位置
        String ip = IpAddressUtil.getClientIpAddress(request);
        String region = IpAddressUtil.getRegionByIp(ip);
        userVO.setRegion(region);

        return ResultUtils.success(userVO);
    }

    /**
     * 登出
     *
     * @param delectRequest
     * @param request
     * @return
     */
    @PostMapping("/logout")
    public BaseResponse<Boolean> userLogout(@RequestBody DelectRequest delectRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(delectRequest == null, ErrorCode.PARAM_ERROR);
        boolean result = userService.userLogout(delectRequest, request);
        return ResultUtils.success(result);
    }

    /**
     * 根据id获取用户
     */
    @GetMapping("/id")
    public BaseResponse<UserVO> getUserById(@RequestParam Integer id) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAM_ERROR);
        User user = userService.getById(id);
        ThrowUtils.throwIf(user == null, ErrorCode.RESOURCE_NOT_FOUND);
        return ResultUtils.success(userService.getUserVOById(id));
    }

    /**
     * 获取当前登录用户
     *
     * @param request
     * @return
     */
    @GetMapping
    public BaseResponse<UserVO> getCurrentUser(HttpServletRequest request) {
        ThrowUtils.throwIf(request == null, ErrorCode.PARAM_ERROR, "请求为空");
        ThrowUtils.throwIf(!userService.isLogin(request), ErrorCode.NOT_LOGIN, "用户未登录");
        User loginUser = userService.getLoginUser(request);
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN, "用户未登录");
        UserVO userVO = userService.getUserVOById(loginUser.getId());
        // 获取用户IP地址和地理位置
        String region = userService.getUserRegion(request);
        userVO.setRegion(region);
        return ResultUtils.success(userVO);
    }

    /**
     * 注销账号
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteUser(@RequestBody DelectRequest deleteRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(deleteRequest == null || deleteRequest.getId() == null,
                ErrorCode.PARAM_ERROR, "用户ID不能为空");
        boolean result = userService.deleteUser(deleteRequest, request);
        return ResultUtils.success(result);
    }


    /**
     * 编辑用户
     *
     * @param userUpdateRequest
     * @param request
     * @return
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> updateUser(@RequestBody UserUpdateRequest userUpdateRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(userUpdateRequest == null || userUpdateRequest.getId() == null,
                ErrorCode.PARAM_ERROR, "用户ID不能为空");
        boolean result = userService.updateUser(userUpdateRequest, request);
        return ResultUtils.success(result);
    }

    /**
     * 获取用户列表
     *
     * @param userQueryRequest
     * @return
     */
    @PostMapping("/list")
    public BaseResponse<Page<UserVO>> listUser(@RequestBody UserQueryRequest userQueryRequest) {
        Page<UserVO> userVOList = userService.listUserVO(userQueryRequest);
        return ResultUtils.success(userVOList);
    }


    /**
     * 上传头像
     *
     * @param file
     * @param request
     * @return
     */
    @PostMapping("/uploadAvatar")
    public BaseResponse<Boolean> uploadAvatar(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        boolean result = userService.uploadAvatar(file, request);
        return ResultUtils.success(result);
    }

    /**
     * 关注
     */
    @PostMapping("/follow")
    public BaseResponse<Boolean> follow(@RequestBody UserFollowAddRequest userFollowRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(userFollowRequest == null || userFollowRequest.getFollowingId() == null,
                ErrorCode.PARAM_ERROR, "用户ID不能为空");
        boolean result = userFollowService.follow(userFollowRequest, request);
        return ResultUtils.success(result);
    }

    /**
     * 取消关注
     */
    @PostMapping("/unfollow")
    public BaseResponse<Boolean> unfollow(@RequestBody UserFollowAddRequest userFollowRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(userFollowRequest == null || userFollowRequest.getFollowingId() == null,
                ErrorCode.PARAM_ERROR, "用户ID不能为空");
        boolean result = userFollowService.unfollow(userFollowRequest, request);
        return ResultUtils.success(result);
    }

    /**
     * 检查是否关注用户
     */
    @GetMapping("/isFollow")
    public BaseResponse<Boolean> isFollow(@RequestParam Integer followingId, HttpServletRequest request) {
        ThrowUtils.throwIf(followingId == null, ErrorCode.PARAM_ERROR, "用户ID不能为空");
        User loginUser = userService.getLoginUser(request);
        boolean exists = userFollowService.lambdaQuery().eq(UserFollow::getFollowerId, loginUser.getId()).eq(UserFollow::getFollowingId, followingId).exists();
        return ResultUtils.success(exists);
    }

    /**
     * 获取用户喜欢的笔记列表
     */
    @PostMapping("/like_notes")
    public BaseResponse<List<NotesVO>> getLikeNotes(HttpServletRequest request, @RequestBody PageRequest pageRequest) {
        User loginUser = userService.getLoginUser(request);
        QueryWrapper<NoteLike> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", loginUser.getId());
        Page<NoteLike> page = noteLikeService.page(new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize()), queryWrapper);
        // 转换为NoteVO
        List<NotesVO> noteVOList = page.getRecords().stream().map(noteLike -> {
            Notes note = notesServiceImpl.getById(noteLike.getNoteId());
            return notesServiceImpl.buildNotesVo(note);
        }).collect(Collectors.toList());
        return ResultUtils.success(noteVOList);
    }

    /**
     * 获取用户关注列表（分页）
     */
    @GetMapping("/following")
    public BaseResponse<Page<UserVO>> getFollowing(HttpServletRequest request, @RequestBody PageRequest pageRequest) {
        User loginUser = userService.getLoginUser(request);
        Page<UserFollow> userFollowPage = userFollowService.lambdaQuery()
                .eq(UserFollow::getFollowerId, loginUser.getId())
                .page(new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize()));

        List<UserVO> userVOList = userFollowPage.getRecords().stream().map(userFollow -> {
            User user = userService.getById(userFollow.getFollowingId());
            return UserVO.toVO(user);
        }).collect(Collectors.toList());

        Page<UserVO> userVOPage = new Page<>(userFollowPage.getCurrent(), userFollowPage.getSize(), userFollowPage.getTotal());
        userVOPage.setRecords(userVOList);

        return ResultUtils.success(userVOPage);
    }

    /**
     * 获取用户粉丝列表（分页）
     */
    @GetMapping("/follower")
    public BaseResponse<Page<UserVO>> getFollower(HttpServletRequest request, @RequestBody PageRequest pageRequest) {
        User loginUser = userService.getLoginUser(request);
        Page<UserFollow> userFollowPage = userFollowService.lambdaQuery()
                .eq(UserFollow::getFollowingId, loginUser.getId())
                .page(new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize()));

        List<UserVO> userVOList = userFollowPage.getRecords().stream().map(userFollow -> {
            User user = userService.getById(userFollow.getFollowerId());
            return UserVO.toVO(user);
        }).collect(Collectors.toList());

        Page<UserVO> userVOPage = new Page<>(userFollowPage.getCurrent(), userFollowPage.getSize(), userFollowPage.getTotal());
        userVOPage.setRecords(userVOList);

        return ResultUtils.success(userVOPage);
    }

    // --------------- 管理员专区 ---------------
    /**
     * 获取当前用户（管理员）
     *
     * @param delectRequest
     * @return
     */
    @GetMapping("/admin/id")
    @AuthCheck(requiredRoles = {"admin"})
    public BaseResponse<User> getById(@RequestBody DelectRequest delectRequest) {
        ThrowUtils.throwIf(delectRequest == null, ErrorCode.PARAM_ERROR);
        Integer id = delectRequest.getId();
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAM_ERROR);
        User user = userService.getById(id);
        ThrowUtils.throwIf(user == null, ErrorCode.RESOURCE_NOT_FOUND);
        return ResultUtils.success(user);
    }

    /**
     * 获取用户列表（管理员）
     */
    @PostMapping("/admin/list")
    @AuthCheck(requiredRoles = {"admin"})
    public BaseResponse<Page<User>>  listUserAdmin(@RequestBody UserQueryRequest userQueryRequest) {
        ThrowUtils.throwIf(userQueryRequest == null, ErrorCode.PARAM_ERROR);
        QueryWrapper<User> queryWrapper = userService.getQueryWrapper(userQueryRequest);
        Page<User> page = userService.page(new Page<>(userQueryRequest.getPageNum(), userQueryRequest.getPageSize()), queryWrapper);
        return ResultUtils.success(page);
    }

    /**
     * 删除用户
     */
    @PostMapping("/admin/delete")
    @AuthCheck(requiredRoles = {"admin"})
    public BaseResponse<Boolean> deleteUser(@RequestBody DelectRequest deleteRequest) {
        ThrowUtils.throwIf(deleteRequest == null || deleteRequest.getId() <= 0, ErrorCode.PARAM_ERROR);
        boolean result = userService.removeById(deleteRequest.getId());
        return ResultUtils.success(result);
    }

    /**
     * 修改用户
     */
    @PostMapping("/admin/update")
    @AuthCheck(requiredRoles = {"admin"})
    public BaseResponse<Boolean> updateUser(@RequestBody UserEditRequest userUpdateRequest) {
        ThrowUtils.throwIf(userUpdateRequest == null || userUpdateRequest.getId() <= 0, ErrorCode.PARAM_ERROR);
        User user = new User();
        BeanUtils.copyProperties(userUpdateRequest, user);
        boolean result = userService.updateById(user);
        return ResultUtils.success(result);
    }


}
